#encoding=utf-8

import math
"""
basic data structure
"""
class Stockdata:
    openp=0.0
    lowp=0.0
    highp=0.0
    closep=0.0
    volumn = 0
    
    def __str__(self):
        return str(self.openp) + " " + str(self.lowp) + " " + str(self.highp) + " " + str(self.closep)

    def __repr__(self):
        return str(self.openp) + " " + str(self.lowp) + " " + str(self.highp) + " " + str(self.closep) + " " + str(self.volumn)
"""
-----------mssd-------------
"""
"""
    calclate n day ema
    x is the list sequence of close price
    from 0 to n, n represents the current
"""

def _ema(l, n):
    ema_curr = []

    for i in range(0, len(l)):
        ema_curr.append(float(0.0))
    
    ema_curr[0] = float(l[0])
    #ema_curr[0] = 0.0
    
    for i in range(1, len(l)):
        ema_curr[i] = (2*float(l[i]) + (n-1)*ema_curr[i-1]) / (n+1)
        
    return ema_curr

def ema(x, n):
    ema_curr = []

    for i in range(0, len(x)):
        ema_curr.append(float(0.0))
    
    ema_curr[0] = float(x[0].closep)
    #ema_curr[0] = 0.0
    
    for i in range(1, len(x)):
        ema_curr[i] = (2*float(x[i].closep) + (n-1)*ema_curr[i-1]) / (n+1)
        
    return ema_curr


def dif(x):
    dif = []
    for i in range(0, len(x)):
        ema12 = ema(x, 12)[i]
        ema26 = ema(x, 26)[i]
        dif.append(ema12-ema26)
    return dif

def dea(x, d):
    dea_curr = []
    for i in range(0, len(x)):
        dea_curr.append(0.0)

    difs = dif(x)
    dea_curr[0] = difs[0]

    for i in range(1, len(x)):
        dea_curr[i] = (dea_curr[i-1]*(d-1) + difs[i]*2) / (d+1)
    
    return dea_curr

def macd(x):
    macds = []
    difs = dif(x)
    dea9s = dea(x, 9)
    
    for i in range(0, len(x)):
        macd = 2*(difs[i] - dea9s[i])
        macds.append(macd)
        
    return macds

"""
---------------KDJ--------------

"""
def rsv(x, d):
    rsvs = []
    
    startd = 0
    if len(x) > d:
        startd = len(x) - d

    ln = x[startd].lowp
    hn = x[startd].highp

    for i in range(startd, len(x)):
        if x[i].lowp < ln:
            ln = x[i].lowp
        if x[i].highp > hn:
            hn = x[i].highp

    #print ln, hn
    for i in range(startd, len(x)):
        try:
            rsvn = (x[i].closep - ln) / (hn - ln) * 100.0
        except:
            rsvn = 1.0
        
        rsvs.append(rsvn)
    
    return rsvs

def kdj(x):
    curr_k = []
    curr_d = []
    curr_j = []
    
    rsvs = rsv(x[0:1], 9)
    
    for i in range(0, len(x)):
        curr_k.append(0.0)
        curr_d.append(0.0)
        curr_j.append(0.0)

    #initial 0 for k and d
    curr_k[0] = 0*2/3.0 + rsvs[0] / 3.0
    curr_d[0] = 0*2/3.0 + curr_k[0] / 3.0
    curr_j[0] = 3*curr_k[0] - 2*curr_d[0]
    
    for i in range(1, len(x)):
        rsvs = rsv(x[0:i+1], 9)
        curr_k[i] = 2*curr_k[i-1]/3.0 + rsvs[len(rsvs)-1] / 3.0
        curr_d[i] = 2*curr_d[i-1]/3.0 + curr_k[i] / 3.0
        curr_j[i] = 3*curr_k[i] - 2*curr_d[i]
    
    return (curr_k, curr_d, curr_j)

"""
----------------------BRAR--------------------
"""
def brar(x, d):
    up_list = []
    down_list = []
    up_forces = []
    down_forces = []

    up_strength = 0
    down_strength = 0

    up_force = x[0].highp - x[0].openp
    down_force = x[0].openp - x[0].lowp

    up_list.append(up_strength)
    down_list.append(down_strength)
    up_forces.append(up_force)
    down_forces.append(down_force)
        
    for i in range(1, len(x)):
        up_strength = x[i].highp - x[i-1].closep
        down_strength = x[i-1].closep - x[i].lowp

        up_force = x[i].highp - x[i].openp
        down_force = x[i].openp - x[i].lowp
        
        if up_strength < 0:
            up_strength = 0
            
        if  down_strength < 0:
            down_strength = 0

        up_list.append(up_strength)
        down_list.append(down_strength)
        up_forces.append(up_force)
        down_forces.append(down_force)
        
    startd = 0
    if len(x) > d:
        startd = len(x) - d
    
    up_sum = sum(up_list[startd:len(x)])
    down_sum = sum(down_list[startd:len(x)])
    
    try:
        br = up_sum / down_sum * 100.0
    except:
        br = None
        
    push_sum = sum(up_forces[startd:len(x)])
    pop_sum  = sum(down_forces[startd:len(x)])

    try:
        ar = push_sum / pop_sum * 100
    except:
        ar = None
        
    return br, ar

"""
----------------------cr---------------------
"""
def cr(x, d):
    up_list = []
    down_list = []
    up_forces = []
    down_forces = []

    up_strength = 0.0
    down_strength = 0.0
    
    up_list.append(up_strength)
    down_list.append(down_strength)
   
    for i in range(1, len(x)):
        up_strength = x[i].highp - (x[i-1].lowp + x[i-1].highp)/2
        down_strength = (x[i-1].lowp + x[i-1].highp)/2 - x[i].lowp

        if up_strength < 0:
            up_strength = 0
            
        if  down_strength < 0:
            down_strength = 0

        up_list.append(up_strength)
        down_list.append(down_strength)
      
    startd = 0
    if len(x) > d:
        startd = len(x) - d
    
    up_sum = sum(up_list[startd:len(x)])
    down_sum = sum(down_list[startd:len(x)])
    
    try:
        cr = up_sum / down_sum * 100.0
    except:
        cr = None
   
    return cr

def dmi(x, d):
    tr1s = []
    pdms = []
    mdms = []
    for i in range(0, len(x)):
        tr1s.append(0.0)
    
    for i in range(1, len(x)):
        tr1s[i] = max(x[i].closep - x[i].lowp,
                      x[i].highp - x[i-1].closep,
                      x[i].lowp  - x[i-1].closep)

        pdms[i] = max(x[i].highp - x[i-1].highp, 0)
        mdms[i] = max(x[i].lowp - x[i-1].lowp, 0)

    startd = 0
    if len(x) > d:
        startd = len(x) - d
    
    tr_d = sum(tr1s[startd:len(x)])
    pdm_d = sum(pdms[startd:len(x)])           
    mdm_d = sum(mdms[startd:len(x)])

    try:
        pdi_d = pdm_d / tr_d
    except:
        pdi_d = None

    try:
        mdi_d = mdm_d / tr_d
    except:
        mdi_d = None

    di_delta = pdi_d - mdi_d
    di_accum = pdi_d + mdi_d
    dx = di_delta - di_accum

    return 0

def vr(x, d):
    avs = []
    bvs = []
    cvs = []
    vrs  = []

    for i in range(0, len(x)):
        avs.append(0.0)
        bvs.append(0.0)
        cvs.append(0.0)
        vrs.append(0.0)
    
    startd = 1
    if len(x) > d:
        startd = len(x) - d

    index = len(x)-1
    for i in range(startd, len(x)):
        if (x[i].closep - x[i-1].closep) > 0:
            avs[index] += x[i].volumn
        elif (x[i].closep - x[i-1].closep) < 0:
            bvs[index] += x[i].volumn
        else:
            cvs[index] += x[i].volumn

    try:
        vrs[index] = 100.0*(avs[i] + 0.5*cvs[i]) / (bvs[i] + 0.5*cvs[i])
    except:
        vrs[index] = None

    vrs[0] = None
    
    for i in range(index-1, 1, -1):
        avs[i] = avs[i+1]
        bvs[i] = bvs[i+1]
        cvs[i] = cvs[i+1]
        if (x[i+1].closep - x[i].closep) > 0:
            avs[i] -= x[i+1].volumn
        elif (x[i+1].closep - x[i].closep) < 0:
            bvs[i] -= x[i+1].volumn
        else:
            cvs[i] -= x[i+1].volumn
        
        if i - d >= 0:
            if (x[i-d+1].closep - x[i-d].closep) > 0:
                avs[i] += x[i-d+1].volumn
            elif (x[i-d+1].closep - x[i-d].closep) < 0:
                bvs[i] += x[i-d+1].volumn
            else:
                cvs[i] += x[i-d+1].volumn
        
        try:
            vrs[i] = 100.0*(avs[i] + 0.5*cvs[i]) / (bvs[i] + 0.5*cvs[i])
        except:
            vrs[i] = None
    
    return vrs


def obv(x):
    obvs = []

    for i in range(0, len(x)):
        obvs.append(0)

    obvs[0] = x[0].volumn
    for i in range(1, len(x)):
        if x[i].closep - x[i-1].closep > 0:
            sgn = 1
        elif x[i].closep - x[i-1].closep < 0:
            sgn = -1
        else:
            sgn = 0
            
        obvs[i] = obvs[i-1] + sgn*x[i].volumn

    return obvs

def wvad(x, d):
    wvads = []
    a = []
    b = []
    v = []

    for i in range(0, len(x)):
        a.append(x[i].closep - x[i].openp)
        b.append(x[i].highp - x[i].lowp)
        v.append(x[i].volumn)
    
    for i in range(0, len(x)):
        startd = 0
        if i - d + 1> 0:
            startd = i - d + 1

        s = 0
        for j in range(startd, i+1):
            s += a[j] / b[j]*v[j]

        wvads.append(s)

    return wvads

def cci(x, d):
    typs = []
    cc1s = []
    for i in range(0, len(x)):
        typs.append((x[i].highp + x[i].lowp + x[i].closep) / 3)
    
    for i in range(0, len(x)):
        startd = 0
        if i - d + 1 > 0:
            startd = i - d + 1

        avedev = 0
        #s = sum(typs[startd:(i+1)])
        s = 0
        
        for j in range(startd, i+1):
            s += typs[j]

        avg = s/d
        for j in range(startd, i+1):
            avedev += abs(typs[j]-avg)

        avedev /= d
        try:
            cc1s.append((typs[i] - avg) / (0.015*avedev))
        except:
            cc1s.append(None)
    return cc1s

def boll(x, d):

    startd = 0
    if len(x) - d > 0:
        startd = len(x) - d

    s = 0
    for i in range(startd, len(x)):
        s += x[i].closep

    ma = s/d

    s = 0
    for i in range(startd, len(x)):
        s += (x[i].closep - ma)*(x[i].closep- ma)

    s /= d
    md = math.sqrt(s)
    mb = ma - x[len(x)-1].closep
    up = mb + 2*md
    dn = mb - 2*md

    print ma, md, mb, up, dn

def wr(x, d):
    wrs = []
    #for i in range(len(x)):
    #    wrs.append(0)
    
    for i in range(0, len(x)):
        startd = 0
        if i - d + 1> 0:
            startd = i - d + 1

        hn = 0
        ln = 1000
        for j in range(startd, i+1):
            if x[j].highp > hn:
                hn = x[j].highp
            if x[j].lowp < ln:
                ln = x[j].lowp
        try:
            wms = 100.0* (hn-x[i].closep) / (hn - ln)
        except:
            wms = Non
            
        wrs.append(wms)            

    return wrs

def roc(x, d):
    rocs = []
    
    for i in range(0, len(x)):
        startd = 0
        if i - d + 1> 0:    
            startd = i - d + 1
        else:
            rocs.append(None)
            continue
        ax = x[i].closep - x[startd-1].closep
        bx = x[startd-1].closep
        try:        
            roc_v = 100*(ax / bx)
        except:
            roc_v = None
        rocs.append(roc_v)

    return rocs    

def trix(x, d):
    ax = ema(x, d)
    bx = _ema(ax,d)
    trixs = _ema(bx, d)
    return trixs

def expma(x, d):
    li=[]
    for i in x:
        li.append(i.closep)
    return _ema(li, d)

def _ma(l, d):
    mas = []

    for i in range(0, len(l)):
        startd = 0
        if i - d + 1 > 0:
            startd = i - d + 1
        mas.append(sum(l[startd:i+1]) / (i+1-startd))
    return mas
    
def emv(x, d, m):
    ems = []
    emvs = []
    
    ems.append(0)
    
    for i in range(1, len(x)):    
        a = (x[i].highp + x[i].lowp) / 2
        b = (x[i-1].highp + x[i-1].lowp) / 2
        c = x[i].highp - x[i].lowp
        try:        
            em = (a-b)*c / x[i].volumn
        except:
            em = None
        ems.append(em)
    
    for i in range(1, len(x)):
        startd = 0
        if i - d + 1> 0:    
            startd = i - d + 1
        emvs.append(sum(ems[startd:(i+1)]))

    maemv = _ma(emvs, m)
    return emvs, maemv

def asi(x, dn):
    a = []
    b = []
    c = []
    d = []
    e = []
    f = []
    g = []
    xi = []
    k = []
    r = []
    sis = []
    a.append(0)
    b.append(0)
    c.append(0)
    d.append(0)
    e.append(0)
    f.append(0)
    g.append(0)
    xi.append(0)
    k.append(0)
    r.append(0)

    for i in range(len(x)):        
        sis.append(0)

    for i in range(1, len(x)):
        a.append(abs(x[i].highp - x[i-1].closep))
        b.append(abs(x[i].lowp  - x[i-1].closep))
        c.append(abs(x[i].highp - x[i-1].lowp))
        d.append(abs(x[i-1].closep - x[i-1].openp))
        e.append((x[i].closep - x[i-1].closep))
        f.append((x[i].closep - x[i].openp))
        g.append((x[i-1].closep - x[i-1].openp))
        xi.append(e[i]+f[i]*0.5+g[i])
        k.append(max(a[i], b[i]))
        if a[i] == max(a[i], b[i], c[i]):
            r.append(a[i] + 0.5*b[i] + 0.25*d[i])
        elif b[i] == max(a[i], b[i], c[i]):
            r.append(b[i] + 0.5*a[i] + 0.25*d[i])
        else:
            r.append(c[i] + 0.25*d[i])
        l = dn
        try:
            startd = 0
            if i - dn + 1> 0:    
                startd = i - dn + 1
            v = 50*xi[i]/r[i]*k[i]/l
            n = (i-startd+1)
            sis[i] = sis[i-1] + v
        except Exception, ex:
            print ex
            sis[i]=None
    
    return sis

def _sma(l, n, m):
    sma_curr = []

    for i in range(0, len(l)):
        sma_curr.append(float(0.0))
    
    sma_curr[0] = float(l[0])
    
    for i in range(1, len(l)):
        sma_curr[i] = (m*float(l[i]) + (n-m)*sma_curr[i-1]) / (n)
        
    return sma_curr
        
    
def rsi(x, d):
    rsis = []
    rsis.append(100)
    for i in range(1, len(x)):
        startd = 0
        if i - d + 1> 0:    
            startd = i - d + 1

        liu = []
        li = []
        for j in range(startd, i+1):
            if j-1 >= 0:
                t=x[j].closep- x[j-1].closep
            else:
                t = 0
            if t> 0:
                liu.append(t)
            li.append(abs(t))

        try:
            #print liu, li
            rsis.append(sum(liu)/ (sum(li)) * 100.0)
        except:
            rsis.append(None)
            
    return rsis

if __name__ == "__main__":
    import yahoo
    #li=yahoo.get_historical_prices('002336.sz', '19900101', '20110309')
    li=yahoo.get_historical_prices('002336.sz', '19900101', '20100201')
    l = []
    for i in range(1, len(li)):
        sd = Stockdata()
        sd.closep = float(li[i][4])
        sd.openp  = float(li[i][1])
        sd.highp  = float(li[i][2])
        sd.lowp   = float(li[i][3])
        sd.volumn = float(li[i][5])
        l.append(sd)

    l.reverse()
    print l
    #print dif(l)
    #print dea(l, 9)
    #print macd(l)
    #kdjs = kdj(l)
    #print kdjs[0]
    #print kdjs[1]
    #print kdjs[2]

    #print brar(l, 26)
    #print cr(l, 26)

    #print vr(l, 26)
    #print obv(l)
    #print wvad(l, 24) #not veryfied
    #print cci(l, 14)
    #boll(l, 20)  #not veryfied
    #print wr(l, 6) 
    #print roc(l, 12) 
    #print trix(l, 12) #not veryfied
    #print expma(l, 12)
    #print emv(l, 14, 9)[0] #not veryfied
    #print emv(l, 14, 9)[1] #not veryfied
    #print asi(l, 6) 0.02
    print rsi(l, 6)  #not veryfied
    